package com.star.system.service.impl;

import cn.hutool.core.lang.Assert;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.star.common.utils.DictEnums;
import com.star.common.vo.DictVO;
import com.star.system.dto.DictSaveDTO;
import com.star.system.dto.DictUpdateDTO;
import com.star.system.dto.DictUpdateTypeDTO;
import com.star.system.enums.TypeCode;
import com.star.system.struct.DictStruct;
import com.star.system.entity.Dict;
import com.star.system.mapper.DictMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.star.system.service.DictService;
import com.star.system.vo.DictData;
import com.star.system.vo.DictType;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 字典 服务实现类
 *
 * @author yangzj
 */
@Service
public class DictServiceImpl extends ServiceImpl<DictMapper, Dict> implements DictService {

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(DictSaveDTO dto) {
        this.save(DictStruct.INSTANCE.to(dto));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(DictUpdateDTO dto) {
        this.update(DictStruct.INSTANCE.to(dto), Wrappers.<Dict>lambdaUpdate()
                .eq(Dict::getId, dto.getId())
                .set(Dict::getExpand, dto.getExpand()));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void updateType(DictUpdateTypeDTO dto) {
        Dict dict = Assert.notNull(this.getById(dto.getId()), "字典不存在");
        this.updateBatchById(this.lambdaQuery().eq(Dict::getTypeCode, dict.getTypeCode()).list()
                .stream().map(c -> new Dict().setId(c.getId())
                        .setTypeCode(dto.getTypeCode())
                        .setTypeName(dto.getTypeName()))
                .collect(Collectors.toList()));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByType(String typeCode) {
        this.lambdaUpdate().in(Dict::getTypeCode, typeCode).remove();
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteByIds(List<Long> ids) {
        this.removeByIds(ids);
    }

    @Override
    public List<DictVO> listAll() {
        List<DictVO> list = baseMapper.listAll();
        list.addAll(DictEnums.getEnums());
        return list;
    }

    @Override
    public List<DictType> listType() {
        return baseMapper.listType();
    }

    @Override
    public List<DictData> listData(String typeCode) {
        return baseMapper.listData(typeCode);
    }

    @Override
    public List<DictData> listData(TypeCode typeCode) {
        return this.listData(typeCode.name().toLowerCase(Locale.ROOT));
    }

    @Override
    public Map<String, String> getMapForCode(TypeCode typeCode) {
        return this.listData(typeCode).stream().collect(Collectors.toMap(DictData::getCode, DictData::getName));
    }

    @Override
    public Map<String, String> getMapForName(TypeCode typeCode) {
        return this.listData(typeCode).stream().collect(Collectors.toMap(DictData::getName, DictData::getCode));
    }

    @Override
    public Set<String> listDataName(TypeCode typeCode) {
        return this.listData(typeCode).stream().map(DictData::getName).collect(Collectors.toSet());
    }

}
